package com.bjsxt;
//使用this作为线程对象锁    在不同线程中，相同对象中的synchronized会互斥
/*synchronized () 方法可以在任意一个类中的方法实现，不一定要继承Thread的类*/

//使用自定义对象作为线程对象锁
//在不同线程中，拥有相同自定义对象中的synchronized 会互斥
// 语法结构：synchronized(自定义对象){ 同步代码 }

/*定义程序员类*/
class Programmer{
    private String name;
    public Programmer(String name){
        this.name=name;
    }
    //打开电脑
    //使用synchronized () 首先要考虑哪部分代码需要同步，
    // 再考虑让哪些线程在执行时具有互斥
    //在同一对象下有互斥

    public void computer(){
        //放在方法中
   // public synchronized void computer(){
        //synchronized public void computer(){
        synchronized (this) {
            try {
                System.out.println(this.name + "接通电源");
                Thread.sleep(500);
                System.out.println(this.name + "按下开机键");
                Thread.sleep(500);
                System.out.println(this.name + "系统启动中");
                Thread.sleep(500);
                System.out.println(this.name + "系统启动成功");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    //编码
    public void coding(){
        synchronized (this) {
            try {
                System.out.println(this.name + "双击IDEA");
                Thread.sleep(500);
                System.out.println(this.name + "Idea启动完毕");
                Thread.sleep(500);
                System.out.println(this.name + "写代码");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
//定义经理类
class Manager01{

    private String name01;//经理
    public Manager01(String name01){

        this.name01 = name01;
    }
    public String getName01(){
        return this.name01;
    }
    //传经理  员工
public void cheers01(String mName,String eName){
    try {
        System.out.println(mName + "来到"+eName+"面前");
        Thread.sleep(500);
        System.out.println(eName + "拿起洒杯");
        Thread.sleep(500);
        System.out.println(mName + "和"+eName+"干杯");

    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
}
//打开电脑的工作线程
class Working1 extends Thread{
    private Programmer p;//开电脑的人
    public Working1(Programmer p){
        this.p=p;
    }

    @Override
    public void run() {
        this.p.computer();//调用开电脑方法
    }
}
//编写代码的线程
class Working2 extends Thread{
    private Programmer p;//开电脑的人
    public Working2(Programmer p){
        this.p=p;
    }

    @Override
    public void run() {
        this.p.coding();//调用开电脑方法
    }
}
//敬酒线程
class CheersT extends Thread{
    //经理
    private Manager01 manager01;
    private String name;//员工
    //实例化时传入
    public CheersT(Manager01 manager01,String name){
        this.manager01=manager01;
        this.name=name;
    }
    @Override
    public void run() {
        synchronized (this.manager01) {
            this.manager01.cheers01(this.manager01.getName01(), name);
        }
    }
}
public class TestSynchronized {
    public static void main(String[] args) {
       /* Programmer p = new Programmer("三哥");

        //启动线程  同一个对象
        new Working1(p).start();
        new Working2(p).start();*/
        Manager01 manager = new Manager01("张三丰");
        new CheersT(manager,"张三").start();
        new CheersT(manager,"李四").start();
    }
}
